package com.syq.dao.impl;


import com.mongodb.client.result.UpdateResult;
import com.syq.dao.MongoDBHelper;
import com.syq.dao.MongodbDao;
import com.syq.entity.MongoDBDocument;
import com.syq.entity.MongoDbCondition;
import com.syq.utils.CollectionUtils;
import com.syq.utils.GenNumTools;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @ClassName MongoDBDaoImpl
 * @Desc TODO   MongoDB 工具类
 * @Date 2019/4/1 9:43
 * @Version 1.0
 */
@Component
public class MongodbDaoImpl extends MongoDBHelper implements MongodbDao {


    @Override
    public void insert(MongoDBDocument mongoDBDocument) {
        this.mongoTemplate.insert(mongoDBDocument);
    }

    @Override
    public void insertWithKey(MongoDBDocument mongoDBDocument,String key) {
        this.mongoTemplate.insert(mongoDBDocument,key);
    }

    public void save(MongoDBDocument mongoDBDocument) {
//        Sort sort = Sort.by(Sort.Direction.DESC, "name");
//        mongoDBDocument = mongoTemplate.findOne(Query.query(Criteria.where("")).with(sort), MongoDBDocument.class);
        mongoTemplate.save(mongoDBDocument);
    }


    public void save(MongoDBDocument mongoDBDocument,String collectionName) {
//        Sort sort = Sort.by(Sort.Direction.DESC, "name");
//        mongoDBDocument = mongoTemplate.findOne(Query.query(Criteria.where("")).with(sort), MongoDBDocument.class);
        mongoTemplate.save(mongoDBDocument,collectionName);
    }

    /**
     * 删除文档
     * NOTE:remove方法不支持级联删除所以要单独删除子数据
     * @param name
     */
    public void remove(String name) {
        //根据名字查询数据并删除
        MongoDBDocument mongoDBDocument = mongoTemplate.findOne(Query.query(Criteria.where("name").is(name)), MongoDBDocument.class);
        //remove方法不支持级联删除所以要单独删除子数据
        List<MongoDBDocument> metMongoDBDocuments = null;
        for (MongoDBDocument metMongoDBDocument : metMongoDBDocuments) {
            mongoTemplate.remove(metMongoDBDocument);
        }
        //删除主数据
        mongoTemplate.remove(mongoDBDocument);
    }
    public void removeById(String id ,String collectionName) {
        //根据名字查询数据并删除
        System.out.println("9999");
        System.out.println(id);
        //MongoDBDocument mongoDBDocument = mongoTemplate.findOne(Query.query(Criteria.where("_id").is(id)), MongoDBDocument.class,collectionName);
        Query query = Query.query(Criteria.where("_id").is(id));
        //remove方法不支持级联删除所以要单独删除子数据
//        List<MongoDBDocument> metMongoDBDocuments = null;
//        for (MongoDBDocument metMongoDBDocument : metMongoDBDocuments) {
//            mongoTemplate.remove(metMongoDBDocument);
//        }
        //删除主数据
        mongoTemplate.remove(query,collectionName);
    }

    /**
     * 更新文档
     * @param mongoDBDocument
     */
    public void update(MongoDBDocument mongoDBDocument) {
//        mongoTemplate.updateFirst(Query.query(Criteria.where("name").is(mongoDBDocument.getName())), Update.update("age", mongoDBDocument.getAge()), MongoDBDocument.class);
    }

    /**
     * 查询文档
     * @param name
     */
    public void find(String name) {
        Sort sort = Sort.by(Sort.Direction.DESC, "name");
        List<MongoDBDocument> mongoDBDocumentS = mongoTemplate.find(Query.query(Criteria.where("name").is(name)), MongoDBDocument.class);
        //基于sort排序使用findOne查询最新一条记录
        MongoDBDocument mongoDBDocument = mongoTemplate.findOne(Query.query(Criteria.where("name").is(name)).with(sort), MongoDBDocument.class);
        //模糊查询
        List<MongoDBDocument> mongoDBDocumentList = mongoTemplate.find(Query.query(Criteria.where("name").is(name).regex(name)).with(sort), MongoDBDocument.class);
        //分页查询
        Pageable pageable = PageRequest.of(3, 20, sort);//换spring 5要换成of方法
        List<MongoDBDocument> mongoDBDocumentPageableList = mongoTemplate.find(Query.query(Criteria.where("name").is(name)).with(pageable), MongoDBDocument.class);
        //总数
        long conut = mongoTemplate.count(Query.query(Criteria.where("name").is(name)), MongoDBDocument.class);
        Page<MongoDBDocument> pages = new PageImpl(mongoDBDocumentPageableList, pageable, conut);

    }
    //根据uid分页查询
    public List<MongoDBDocument> page(int page, String uid){
        Query query = new Query();
        query.addCriteria(Criteria.where("uid").is(uid));
        query.with(Sort.by(new Sort.Order(Sort.Direction.DESC,"timestamp")));
        query.limit(20);
        query.skip((page-1)*20);
        return mongoTemplate.find(query, MongoDBDocument.class);

    }

    //根据uid查詢1个
    public  <T> MongoDBDocument<T> findByKey(String collectionName,String no,Class<T> t){
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(no));
        MongoDBDocument<T> one = mongoTemplate.findOne(query, MongoDBDocument.class,collectionName);
        //System.out.println(one);
        return one;
    }
    public  <T> void updateByKey(String collectionName,String key,Class<T> t,String fdName,String fdValue){
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(key));  //_id区分引号 "1"和1
        Update update = new Update();

        update.set(fdName,fdValue);
        //WriteResult upsert = mongoTemplate.updateMulti(query, update, "userList"); //查询到的全部更新
        //WriteResult upsert = mongoTemplate.updateFirst(query, update, "userList"); //查询更新第一条

        UpdateResult userList = mongoTemplate.upsert(query, update, collectionName);

    }
    public List<MongoDBDocument> getListByRegxp(List<MongoDbCondition<String,String>> mongoDbConditions, String collectionName)
    {
        Query query = new Query();
        if (mongoDbConditions != null && mongoDbConditions.size() > 0) {
            List<Criteria> criterias = new ArrayList<Criteria>();
            for ( MongoDbCondition<String,String> mongoDbCondition: mongoDbConditions) {
                Pattern pattern=Pattern.compile("^.*"+mongoDbCondition.getValue()+".*$", Pattern.CASE_INSENSITIVE);
                System.out.println(mongoDbCondition.getKey());
                System.out.println(pattern);
                criterias.add(Criteria.where(mongoDbCondition.getKey()).regex(pattern));
            }
            query.addCriteria(new Criteria ().orOperator(CollectionUtils.convertArrayFromList(criterias,Criteria.class)));
        }
        List<MongoDBDocument> mongoDBDocuments = mongoTemplate.find(query, MongoDBDocument.class,collectionName);
        mongoDBDocuments.forEach(System.out::println);
        return mongoDBDocuments;
    }

    /**
     * 由MongoDB计算出同一用户当前订单的订单号
     * @param urnobegin
     * @return
     */
    public String initId(String urnobegin,String fieldName,String collectionName) {
        List<AggregationOperation> operations = new ArrayList<>();

        Pattern pattern=Pattern.compile("^.*"+urnobegin+".*$", Pattern.CASE_INSENSITIVE);
        Query query = new Query();
        query.with(Sort.by(new Sort.Order(Sort.Direction.ASC,  fieldName)));
        Optional<MongoDBDocument> maxUrnoOp=  Optional.ofNullable(mongoTemplate.findOne(query, MongoDBDocument.class,collectionName));
        String  maxUrno = maxUrnoOp.isPresent()?maxUrnoOp.get().getId():null;
       // String maxUrno = orderFormMapper.getMaxUrno(urnobegin);
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddhhmmss");
        String timeStr = df.format(new Date());
        System.out.println(timeStr);
        String   newUrno= Optional.ofNullable(maxUrno).isPresent()? GenNumTools.initId( urnobegin+timeStr, 1, maxUrno):urnobegin +timeStr+"1";//如果数据库查到最大的主键则处理后生成新的主键否则就生成编号为一的主键
        return newUrno;

    }






}